<template>
	<n-popover v-model:show="show" trigger="click" :placement="placement" :show-arrow="false">
		<template #trigger>
			<div
				class="cursor-pointer flex items-center text-t-1"
				:class="[{ 'text-sm': size === 'small' }, selectedClass]">
				<slot :selectedItem="selectedItem">
					<base-image
						v-if="selectedItem?.img"
						:src="selectedItem.img"
						:type="imgType"
						:default="imgDefault"
						class="mr-1"
						:class="size === 'small' ? 'h-[18px]' : 'h-[22px]'" />
					<base-icon
						v-else-if="selectedItem?.icon"
						:name="selectedItem.icon"
						:size="size === 'small' ? 22 : 18"
						class="mr-1" />
					<base-text class="truncate" :text="selectedItem?.text" :text-t="selectedItem?.textT" />
				</slot>
				<div class="flex-1"></div>
				<base-icon
					name="down2"
					class="ml-1 text-sm duration-300"
					:class="{
						'rotate-180': show
					}"></base-icon>
			</div>
		</template>
		<div class="max-h-[284px] bg-bg-8 rounded-sm overflow-auto">
			<div
				class="bg-bg-8 px-3 flex justify-between items-center app-bg-react"
				:class="[size === 'small' ? 'h-9' : 'h-11', itemClass]"
				:item="item"
				v-for="item in computedOptions"
				:key="item.id"
				@click="onSelect(item.id)">
				<div class="flex items-center">
					<base-image
						v-if="item.img"
						:src="item.img"
						:type="imgType"
						:default="imgDefault"
						class="mr-1"
						:class="size === 'small' ? 'h-[18px]' : 'h-[22px]'" />
					<base-icon
						v-else-if="item.icon"
						:name="item.icon"
						:size="size === 'small' ? 22 : 18"
						class="mr-1" />
					<base-text
						:class="[
							{ 'text-sm': size === 'small' },
							item.id === modelValue ? 'text-primary' : 'text-t-1'
						]"
						:text="item.text"
						:text-t="item.textT" />
				</div>
				<base-icon
					v-if="showTick !== false"
					name="tick"
					class="text-primary ml-1"
					:class="{ 'opacity-0': item.id !== modelValue }"
					size="20" />
			</div>
		</div>
	</n-popover>
</template>

<script lang="ts" setup>
import { computed, PropType, ref } from 'vue'
import { NPopover } from 'naive-ui'
import BaseIcon from '@/components/base/icon/index.vue'
import BaseImage from '@/components/base/image/index.vue'
import BaseText from '@/components/base/text/index.vue'
import { SelectOptions } from '@/types'
import { getItemById } from '@/utils'

type Placement =
	| 'top'
	| 'bottom'
	| 'left'
	| 'right'
	| 'top-start'
	| 'top-end'
	| 'left-start'
	| 'left-end'
	| 'right-start'
	| 'right-end'
	| 'bottom-start'
	| 'bottom-end'

const props = defineProps({
	modelValue: {
		type: [String, Number],
		required: true
	},
	options: {
		type: Array<SelectOptions>,
		default: () => []
	},
	size: {
		type: String,
		default: ''
	},
	hasAll: {
		type: Boolean
	},
	imgType: {
		type: String,
		default: ''
	},
	imgDefault: {
		type: String,
		default: ''
	},
	selectedClass: {
		type: String,
		default: ''
	},
	itemClass: {
		type: String,
		default: ''
	},
	placement: {
		type: String as PropType<Placement>,
		default: 'bottom-end'
	},
	showTick: {
		type: Boolean
	}
})

const emits = defineEmits(['update:modelValue'])

const allItem: SelectOptions = { id: '', textT: 'tip.all' }

const computedOptions = computed(() => {
	if (props.hasAll) {
		return [allItem, ...props.options]
	} else {
		return props.options
	}
})

const show = ref(false)

const selectedItem = computed(() =>
	getItemById<SelectOptions>(computedOptions.value, props.modelValue)
)

const onSelect = (val: string | number) => {
	emits('update:modelValue', val)
	show.value = false
}
</script>
